Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Global shared objects in Progress
There’s another variation on the shared object theme, and this is global shared objects. The first procedure to define an object includes the
GLOBALkeyword in the definition:
This makes the object definition available to the entire session. The same set of objects that can be defined as
NEW SHAREDcan also be defined asNEW GLOBAL SHARED. For example, one procedure can have this global definition:
Any other procedure in the Progress session that is executed after that procedure can have this definition and make use of the same variable:
One tricky aspect to this is the after that procedure requirement. In many applications, it is not easy to determine which of the procedures that might want to reference a value will execute first, and therefore should be the procedure that defines it. Or you might have many procedures that need to reference the value and not know which of them will execute at all in the course of a session.
Progress provides a work-around for this problem. If a procedure defines an object as
NEW GLOBAL SHAREDand another procedure has already registered this definition, then no error results. Progress ignores theNEW GLOBALpart of the second definition and accepts it as a reference to the existingSHAREDobject. This is different from nonglobal shared objects, where a secondNEW SHAREDreference causes a run-time error.For this reason, it is common practice simply to use the
NEW GLOBAL SHAREDsyntax in every procedure that needs to use the objects. Although this is somewhat contradictory to the way the nonglobal shared syntax works, it is reliable behavior.When to consider using global shared objects
You might think that global shared objects are a better way to go in new applications than nonglobal shared objects, because multiple procedures that aren’t necessarily running in a single predictable procedure call stack can all access them. Also, any of the procedures can define them first and others can define them and use them in any order. Thus, you could place a set of global definitions into an include file and include it in every procedure that needs them, without regard for which procedure has to use the
NEWkeyword in its definitions.Up to a point this is correct, but there are good reasons why you should generally avoid global shared objects in new applications:
- Simply having an include file that many procedures depend on is poor practice in a modern application. Any time the list of definitions in this file changes for any reason, every procedure that uses it must be recompiled and potentially redeployed. As you learn more about dynamic language constructs in later chapters, you learn useful alternatives to global shared variables that are more flexible and can change at run time without any code changes or recompilation at all.
- Global shared objects create potential namespace conflicts and possible unintended consequences in your application, precisely because they are global. A global shared object is visible to every procedure in the entire session, and every procedure shares that name and its value. Global shared objects never go out of scope and they can’t be deleted. They exist from the time the first definition is encountered until the session ends. An important aspect of a modern application is that it is as modular as possible, with code and data for a particular module isolated within a set of procedures that can run independently of other modules. What happens when two modules happen to use the same name for a global object? The result is that Progress defines just one object, with a single value, and two different sets of code are trying to use it for different purposes. Very insidious errors can result.
Thus, it’s generally advisable that you should avoid global objects wherever possible. If you do think you want to use them, consider these important guidelines:
- A global shared variable or other object can be somewhat faster to access than an alternative that involves using possibly dynamic language statements to refer to a value defined elsewhere. All the procedures that use the global shared object are pointing directly to its memory just as if it was defined locally. Therefore, you can consider using global shared variables or other objects for a small number of values that are critical to your application, used with great frequency, and truly global in their use.
- Because global shared objects exist in a single namespace across the entire session, and because they can’t be deleted, you should be very careful in naming them. Use a naming convention that prevents any chance of two different procedures using the same name for different purposes. Perhaps the easiest way to do this is to have a single include file for your entire application that holds all its global definitions. Any procedure that needs any of them includes this same file, so that (as long as they are recompiled together) they remain in sync and there isn’t a chance of another developer inadvertently giving another global object the same name.
In the following chapter, you’ll learn about a newer language construct that very definitely is of great use, your own 4GL functions, which you can often use as an alternative to internal procedures.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |